<template>
  <div class="center-panel" :style="{ height: centerHeight }">
    <wordcss
      v-if="$store.state.app.type == 'textbox'"
      :selectedObj="$store.state.app.selectedObj"
    ></wordcss>
    <imagecss
      v-if="$store.state.app.type == 'image'"
      :selectedObj="$store.state.app.selectedObj"
    ></imagecss>

    <canvas
      style="width:100%;height:100%;border:1px solid #ccc"
      id="canvas"
    ></canvas>
    <div class="minimap" style="z-index:999">
      <canvas id="minimap"></canvas>
    </div>
  </div>
</template>

<script>
import wordcss from "./centerPanel/components/wordcss";
import imagecss from "./centerPanel/components/imagecss";

import { mapGetters, mapActions } from "vuex";
import initAligningGuidelines from "@/utils/guidelines.js";
import initManager from "@/utils/overlines.js";
import { debounce } from "@/utils/core.js";

export default {
  components: { wordcss, imagecss },
  name: "centerPanel",
  data() {
    return {
      centerHeight: "",
      WordTool: true,
      imgTool: false,
      canvas: null
    };
  },
  computed: {},
  watch: {
    //监视界面变化
    "$store.state.app.leftState"() {
      this.resizeHeight();
    },
    "$store.state.app.rightState"() {
      this.resizeHeight();
    }
  },
  created() {},
  mounted() {
    fabric.Object.prototype.objectCaching = false;
    fabric.Object.prototype.set({
      borderColor: "blue",
      cornerColor: "white", //激活状态角落图标的填充颜色
      cornerStrokeColor: "#c0c0c0", //激活状态角落图标的边框颜色
      borderOpacityWhenMoving: 1,
      borderScaleFactor: 1,
      cornerSize: 10,
      cornerStyle: "circle", //rect,circle
      centeredScaling: false, //角落放大缩小是否是以图形中心为放大原点
      centeredRotation: true, //旋转按钮旋转是否是左上角为圆心旋转
      transparentCorners: false, //激活状态角落的图标是否透明
      rotatingPointOffset: 5, //旋转距旋转体的距离
      //这里会影响到后面的对齐.... 默认都是 top left
      //   originX: "center",
      //   originY: "center",
      lockUniScaling: false, //只显示四角的操作
      hasRotatingPoint: true, //是否显示旋转按钮
      selectionDashArray: [5, 5]
    });

    var deleteImg = document.createElement("img");
    deleteImg.src =
      "https://www.chuangkit.com/designdist/rotate.svg?b4b96237716b02445af3fe3be560bf52";

    function renderIcon(icon) {
      return function renderIcon(ctx, left, top, styleOverride, fabricObject) {
        var size = this.cornerSize;
        ctx.save();
        ctx.translate(left, top);
        ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle));

        // ctx.fillStyle = "red";
        // ctx.arc(0, 0, size / 2 + 2, 0, 2 * Math.PI);
        // ctx.fill();
        ctx.drawImage(icon, -size / 2, -size / 2, size, size);
        ctx.restore();
      };
    }

    function renderIcon2() {
      return function renderIcon(ctx, left, top, styleOverride, fabricObject) {
        var size = this.cornerSize;
        ctx.save();
        ctx.translate(left, top);
        ctx.rotate(fabric.util.degreesToRadians(fabricObject.angle));

        ctx.fillStyle = "while";
        ctx.fillRect(-size / 2, -size / 2, size, size);
        ctx.strokeStyle = "#c0c0c0";
        ctx.strokeRect(-size / 2, -size / 2, size, size);

        // ctx.drawImage(icon, -size / 2, -size / 2, size, size);
        ctx.restore();
      };
    }

    // function deleteObject(eventData, target) {
    //   var canvas = target.canvas;
    //   canvas.remove(target);
    //   canvas.requestRenderAll();
    // }

    fabric.Object.prototype.controls.mtr.render = renderIcon(deleteImg);
    fabric.Object.prototype.controls.mtr.cornerSize = 14;
    fabric.Object.prototype.controls.mtr.withConnection = false;
    fabric.Object.prototype.controls.mtr.offsetY = 20;
    fabric.Object.prototype.controls.mtr.x = 0;
    fabric.Object.prototype.controls.mtr.y = 0.5;

    fabric.Object.prototype.controls.mt.render = renderIcon2();
    fabric.Object.prototype.controls.mt.cornerSize = 10;
    fabric.Object.prototype.controls.mb.render = renderIcon2();
    fabric.Object.prototype.controls.mb.cornerSize = 10;
    fabric.Object.prototype.controls.mr.render = renderIcon2();
    fabric.Object.prototype.controls.mr.cornerSize = 10;
    fabric.Object.prototype.controls.ml.render = renderIcon2();
    fabric.Object.prototype.controls.ml.cornerSize = 10;

    window.addEventListener("resize", () => {
      this.resizeHeight();
    });
    this.resizeHeight();

    //获取div的高度和宽度

    //创建，然后放一个对象进去
    this.canvas = new fabric.Canvas("canvas", {
      backgroundColor: "rgba(220,220,220,1)"
    });

    const canvas = this.canvas;
    //设置canvas
    this.initCanvas(canvas);

    canvas.selection = true;
    // canvas.hasControls = false
    // canvas.borderColor = '#ff8d23'
    // 禁止选中图层时自定置于顶部
    canvas.preserveObjectStacking = true;
    //以中心点作为缩放
    canvas.centeredScaling = true;

    //这里通过外部传递大小......
    //这里是毫米，物体长宽毫米
    let designSize = { width: 420, height: 285 };

    //出血大小
    let chuxie = 3;

    //画布大小
    let canvasWidth = document.getElementsByClassName("center-panel")[0]
        .offsetWidth,
      canvasHeight = window.innerHeight - 56,
      //初始化显示比例
      currentScale = 0.8,
      workWidth = (designSize.width * 96) / 25.4 + 0.5,
      workHeight = (designSize.height * 96) / 25.4 + 0.5,
      workWidthNew = workWidth,
      workHeightNew = workHeight;

    let zoom = 1;

    //canvas 总是屏幕大小 内部元素居中
    canvas.setWidth(canvasWidth);
    canvas.setHeight(canvasHeight);

    //根据图像大小，考虑缩略图的大小
    //定义一个缩略图
    const minimap = new fabric.Canvas("minimap", {
      selection: false,
      backgroundColor: "black"
    });

    //计算缩略图导航画布大小
    let minWidth = 0,
      minHeight = 0,
      //放大1.2倍显示
      miniScale = 1.2;
    {
      let constLength = 100;

      //把图像缩小到比例框里面
      if (workWidth > workHeight) {
        minWidth = workWidth / (workHeight / constLength);
        minHeight = constLength;
      } else {
        minHeight = workHeight / (workWidth / constLength);
        minWidth = constLength;
      }
    }

    //初始化大小，把图像缩放到里面
    minimap.setWidth(minWidth * miniScale);
    minimap.setHeight(minHeight * miniScale);

    //判断缩放
    if (canvasWidth < workWidth || canvasHeight < workHeight) {
      //按照长边缩放
      if (workWidth / canvasWidth > workHeight / canvasHeight) {
        zoom = workWidth / (canvasWidth * currentScale);
        workWidthNew = canvasWidth * currentScale;
        workHeightNew = workHeight / zoom;
      } else {
        //按照高度缩放
        zoom = workHeight / (canvasHeight * currentScale);
        workWidthNew = workWidth / zoom;
        workHeightNew = canvasHeight * currentScale;
      }
    }

    //初始化画布大小，这里面居中，应该是实时绘制??

    //绘制工作区域画布大小 不是canvas
    var rect = new fabric.Rect({
      left: ((canvasWidth - workWidthNew) / 2) * zoom,
      top: ((canvasHeight - workHeightNew) / 2) * zoom,
      originX: "left",
      originY: "top",
      width: workWidth,
      height: workHeight,
      fill: "rgba(255,255,255,1)",
      selectable: false,
      transparentCorners: false,
      evented: false,
      excludeFromExport: true,
      hasControls: false,
      perPixelTargetFind: false,
      lxwname: "_lxw_",
      type: "_lxw_bg"
    });

    //缩放 再继续缩小到currentScale
    canvas.setZoom(1 / zoom);
    canvas.add(rect);

    // var text = new fabric.Text("Honey,\nI'm subtle", {
    //   fontSize: 250,
    //   left: 600,
    //   top: 300,
    //   lineHeight: 1,
    //   originX: "left",
    //   statefullCache: true,

    //   scaleX: 0.4,
    //   scaleY: 0.4,
    //   //用渐变作为背景，从什么地方到什么地方
    //   fill: new fabric.Gradient({
    //     type: "linear",
    //     coords: { x1: "0", y1: "0", x2: 100, y2: 200 },
    //     colorStops: [
    //       { color: "red", offset: 0 },
    //       { color: "yellow", offset: 1 }
    //     ]
    //   })
    // });

    // canvas.add(text);
    //改变窗口的时候，canvas也改变，中间的画布也改变大小
    //通过缩略图进行内容导航，不要增加滚动条
    this.addcanvasEventListener(canvas);

    initAligningGuidelines(canvas);
    initManager(canvas, minimap, this.$store, miniScale);

    canvas.requestRenderAll();
    //加入到hisrory
    this.saveState();
  },
  beforeDestroy() {
    console.log("beforeDestroy canvas");
  },
  methods: {
    ...mapActions(["initCanvas", "setSelectedObj", "saveState", "del"]),

    addcanvasEventListener(canvas) {
      let ctx = canvas.getSelectionContext();

      canvas.on("object:added", e => {
        //console.log("object:added", e.target);
      });

      canvas.on("object:modified", e => {
        //console.log("object:modified");
        this.saveState();
      });

      //移除的时候记录??可以考虑批量记录。这里可以考虑优化
      canvas.on("object:removed", e => {
        //console.log("object:removed");
        //this.saveState();
      });
      //   canvas.on("object:selected", e => {
      //     console.log("object:selected", e.target);
      //   });
      canvas.on("selection:created", e => {
        //console.log("selection:created", e.target);
        this.setSelectedObj(e.target);
      });
      canvas.on("selection:updated", e => {
        //console.log("selection:updated", e.target);
        this.setSelectedObj(e.target);
      });
      canvas.on("selection:cleared", e => {
        //console.log("selection:cleared");
        this.setSelectedObj(null);
      });
    },
    resizeHeight() {
      const that = this;

      this.$nextTick(() => {
        that.centerHeight = window.innerHeight - 56 + "px";
        that.$forceUpdate();

        //设置最终视窗大小
        //注意border 1px
        this.canvas.setHeight(window.innerHeight - 56 - /*1px=border*/ 1 * 2);
        this.canvas.setWidth(
          document.getElementsByClassName("center-panel")[0].offsetWidth
        );

        //并且居中left偏移
        let bg = this.canvas.getObjects("_lxw_bg")[0];
        let bgRect = bg.getBoundingRect();

        //居中
        this.canvas.viewportTransform[4] =
          (this.canvas.width - bgRect.width) / 2 -
          bg.left * this.canvas.getZoom();

        //设置里面的对象重新计算坐标
        this.canvas.forEachObject(o => {
          o.setCoords();
        });
      });
    }
  }
};
</script>

<style lang="less" scoped>
.minimap {
  position: absolute !important;
  bottom: 20px;
  right: 20px;
}
</style>
